package com.csust.automaticteach.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csust.automaticteach.exception.BusinessException;
import com.csust.automaticteach.exception.ErrorCode;
import com.csust.automaticteach.app.teacher.iflytek.ppt.ApiClient;
import com.csust.automaticteach.model.dto.generateppt.GeneratePptQueryRequest;
import com.csust.automaticteach.model.entity.GeneratePpt;
import com.csust.automaticteach.model.enums.GeneratePptStatusEnum;
import com.csust.automaticteach.model.vo.generateppt.GeneratePptVO;
import com.csust.automaticteach.model.vo.generateppt.response.CheckProgressVO;
import com.csust.automaticteach.service.GeneratePptService;
import com.csust.automaticteach.mapper.GeneratePptMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

import static com.csust.automaticteach.constant.OrderConstant.ASC;

/**
* @author 钰玟
* @description 针对表【t_generate_ppt(生成ppt)】的数据库操作Service实现
* @createDate 2025-07-18 17:18:09
*/
@Service
@Slf4j
public class GeneratePptServiceImpl extends ServiceImpl<GeneratePptMapper, GeneratePpt>
    implements GeneratePptService{

    @Resource
    private ApiClient apiClient;
    @Override
    public QueryWrapper<GeneratePpt> getGeneratePptQueryWrapper(GeneratePptQueryRequest generatePptQueryRequest) {
        Long id = generatePptQueryRequest.getId();
        String title = generatePptQueryRequest.getTitle();
        String userName = generatePptQueryRequest.getUserName();
        String sortField = generatePptQueryRequest.getSortField();
        String sortOrder = generatePptQueryRequest.getSortOrder();

        QueryWrapper<GeneratePpt> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull( id), "id", id);
        queryWrapper.like(StrUtil.isNotEmpty( title), "title", title);
        queryWrapper.eq(StrUtil.isNotEmpty( userName), "userName", userName);
        queryWrapper.orderBy(StrUtil.isNotEmpty( sortField), sortOrder.equals(ASC), sortField);

        return queryWrapper;
    }

    @Override
    public GeneratePptVO getGeneratePptVO(GeneratePpt record) {
        GeneratePptVO generatePptVO = new GeneratePptVO();
        BeanUtil.copyProperties(record, generatePptVO);
        return generatePptVO;
    }

    @Override
    public List<GeneratePptVO> getGeneratePptVOList(List<GeneratePpt> records) {
        return records.stream().map(this::getGeneratePptVO).toList();
    }

    /**
     * 查询生成ppt进度 并实时返回进度
     *
     * @param sid sid
     * @return 进度
     */
    @Override
    public CheckProgressVO getCheckProgressVOImmediately(String sid) {
        try {
            //调用 apiClient 查询sid
            Mono<CheckProgressVO> progressImmediatelyMono = apiClient.GenerateProgressImmediately(sid);
            CheckProgressVO progressImmediately = progressImmediatelyMono
                    .publishOn(Schedulers.boundedElastic())
                    .map(response -> {
                        String pptUrl = response.getPptUrl();
                        String pptStatus = response.getStatus();
                        //创建updateWrapper
                        UpdateWrapper<GeneratePpt> generatePptUpdateWrapper = new UpdateWrapper<>();
                        if (Objects.equals(GeneratePptStatusEnum.getValueByText(pptStatus), GeneratePptStatusEnum.DONE.getValue())) {
                            log.info("The ppt has been generated successfully, the ppt url is {}", pptUrl);
                            generatePptUpdateWrapper.set("status", GeneratePptStatusEnum.DONE.getValue());
                        }
                        generatePptUpdateWrapper.set("pptUrl", pptUrl).eq("sid", sid);
                        this.update(generatePptUpdateWrapper);
                        return response;
                    }).block();
            if (progressImmediately != null) {
                //返回进度对象
                return progressImmediately;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        } catch (ApiClient.NotReadyImmediateException e) {
            //是自定义的异常类=>代表是正常的获取进度
            CheckProgressVO checkProgressVO = e.getCheckProgressVO();
            log.info("通过 NotReadyImmediateException 实时获取进度:{}", checkProgressVO);
            return checkProgressVO;
        } catch (IOException e) {
            log.error("fail to get the generation progress ,the reason is:" + e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
    }
}




